//
//  HelloWorldLayer.m
//  voyage
//
//  Created by Stéphane BONIFFACY on 17/01/13.
//  Copyright Steph 2013. All rights reserved.
//

//
//  HelloWorldLayer.m
//  voyage
//
//  Created by Stéphane BONIFFACY on 17/01/13.
//  Copyright Steph 2013. All rights reserved.
//

#import "SimpleAudioEngine.h"
// Import the interfaces
#import "HelloWorldLayer.h"
#import "GameOverLayer.h"

// Needed to obtain the Navigation Controller
#import "AppDelegate.h"

#pragma mark - HelloWorldLayer


#define IPHONE_SCALE (UI_USER_INTERFACE_IDIOM()==UIUserInterfaceIdiomPhone?0.42:1.0f)

#define CENTRE_TERRE_Y -320*IPHONE_SCALE

#define RAYON_CANNON 516*IPHONE_SCALE

@interface Explosion: NSObject
{
    float _time;
    CCParticleSystemQuad* _boom;
}

@property(nonatomic,retain) CCParticleSystemQuad* boom;

-(id)initBoom:(CCParticleSystemQuad*)boom withTime:(float)time;

@end

@implementation Explosion

@synthesize boom=_boom;
-(id)initBoom:(CCParticleSystemQuad*)boom withTime:(float)time{
    if(self = [super init])
    {
        _time = time;
        
        self.boom = boom;
    }
    
    return self;
}

-(void)dealloc{
    
    [_boom release];
    [super dealloc];
}

@end


@interface HelloWorldLayer ()
{
    NSMutableArray* _monsters;
    NSMutableArray* _projectiles;
    int             _monstersDestroyed;
    CCSprite*       _player;
    CCSprite*       _stars;
    CCSprite*       _stars2;
    CCSprite*       _terre;
    float           _currentAngle;
    float           _angleCoin;
    CGPoint         _toLocation;
    
    NSMutableArray* _explosions;
    
}

-(void)gameLogic:(ccTime)dt;
-(void)addMonster;
-(void)createProjectile:(ccTime)dt;
-(void)update:(ccTime)dt;
-(void)scrollBackGround:(ccTime)dt;
-(void)moveCannon:(ccTime)dt;

@end

// HelloWorldLayer implementation
@implementation HelloWorldLayer

// Helper class method that creates a Scene with the HelloWorldLayer as the only child.
+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
-(id) init
{
	// always call "super" init
	// Apple recommends to re-assign "self" with the "super's" return value
	if( (self=[super initWithColor:ccc4(0,0,0,0)]) ) {
        /*
         //
         // Leaderboards and Achievements
         //
         
         // Default font size will be 28 points.
         [CCMenuItemFont setFontSize:28];
         
         // Achievement Menu Item using blocks
         CCMenuItem *itemAchievement = [CCMenuItemFont itemWithString:@"Achievements" block:^(id sender) {
         
         
         GKAchievementViewController *achievementViewController = [[GKAchievementViewController alloc] init];
         achievementViewController.achievementDelegate = self;
         
         AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
         
         [[app navController] presentModalViewController:achievementViewController animated:YES];
         
         [achievementViewController release];
         }
         ];
         
         // Leaderboard Menu Item using blocks
         CCMenuItem *itemLeaderboard = [CCMenuItemFont itemWithString:@"Leaderboard" block:^(id sender) {
         
         
         GKLeaderboardViewController *leaderboardViewController = [[GKLeaderboardViewController alloc] init];
         leaderboardViewController.leaderboardDelegate = self;
         
         AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
         
         [[app navController] presentModalViewController:leaderboardViewController animated:YES];
         
         [leaderboardViewController release];
         }
         ];
         
         CCMenu *menu = [CCMenu menuWithItems:itemAchievement, itemLeaderboard, nil];
         
         [menu alignItemsHorizontallyWithPadding:20];
         [menu setPosition:ccp( size.width/2, size.height/2 - 50)];
         
         // Add the menu to the layer
         [self addChild:menu];*/
        
        CGSize winSize = [CCDirector sharedDirector].winSize;
        
               
        _stars = [CCSprite spriteWithFile:@"stars.png"];
        _stars.position = ccp(winSize.width/2, winSize.height/2);
        [self addChild:_stars z:-2 tag:999];
        _stars2 = [CCSprite spriteWithFile:@"stars.png"];
        _stars2.position = ccp(_stars.position.x - _stars.contentSize.width , winSize.height/2);
        [self addChild:_stars2 z:-2 tag:999];
        
        _terre = [CCSprite spriteWithFile:@"terre.png"];
        _terre.position = ccp(winSize.width/2, _terre.contentSize.height/2);
        [self addChild:_terre z:-1 tag:998];
        
        _player = [CCSprite spriteWithFile:@"cannon.png"];
        _player.position = ccp(winSize.width/2, RAYON_CANNON+CENTRE_TERRE_Y);
        _currentAngle = M_PI/2;
        
        _angleCoin = atanf((float)(winSize.height- CENTRE_TERRE_Y)/ (float)(winSize.width/2));
        
        [self addChild:_player];
        
        [self schedule:@selector(gameLogic:) interval:1.0];
        [self schedule:@selector(update:)];
        
        [self setTouchEnabled:YES];
        
        _monsters = [[NSMutableArray alloc] init];
        _projectiles = [[NSMutableArray alloc] init];
        _explosions = [[NSMutableArray alloc] init];
        
        //[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"background-music-aac.caf"];
        
        CCLabelTTF *label = [CCLabelTTF labelWithString:@"Stop This Alien Space Traffic !!!" fontName:@"Helvetica-Bold" fontSize:32];
        [label setColor:ccc3(255, 255,191)];
        label.scale = IPHONE_SCALE;
        label.position =  ccp( winSize.width /2 , winSize.height-label.contentSize.height*IPHONE_SCALE/2 );
        
		[self addChild: label];
                
	}
	return self;
}

// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
	// in case you have something to dealloc, do it in this method
	// in this particular example nothing needs to be released.
	// cocos2d will automatically release all the children (Label)
 
    [_monsters release];
    _monsters = nil;
    [_projectiles release];
    _projectiles = nil;
	
    
	// don't forget to call "super dealloc"
    [super dealloc];
}

/*#pragma mark GameKit delegate
 
 -(void) achievementViewControllerDidFinish:(GKAchievementViewController *)viewController
 {
 AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
 [[app navController] dismissModalViewControllerAnimated:YES];
 }
 
 -(void) leaderboardViewControllerDidFinish:(GKLeaderboardViewController *)viewController
 {
 AppController *app = (AppController*) [[UIApplication sharedApplication] delegate];
 [[app navController] dismissModalViewControllerAnimated:YES];
 }*/

-(void)addMonster {
    
    CCSprite * monster = [CCSprite spriteWithFile:@"alien.png"];
    
    monster.tag = 1;
    [_monsters addObject:monster];
    
    // Determine where to spawn the monster along the Y axis
    CGSize winSize = [CCDirector sharedDirector].winSize;
    int minY = (_terre.contentSize.height-50);
    int maxY = winSize.height - monster.contentSize.height/2;
    int rangeY = maxY - minY;
    int actualY = (arc4random() % rangeY) + minY;
    
    // Create the monster slightly off-screen along the right edge,
    // and along a random position along the Y axis as calculated above
    monster.position = ccp(winSize.width+monster.contentSize.width/2, actualY-50);
    [self addChild:monster];
    
    // Determine speed of the monster
    int minDuration = 5.0;
    int maxDuration = 7.0;
    int rangeDuration = maxDuration - minDuration;
    int actualDuration = (arc4random() % rangeDuration) + minDuration;
    
    // Create the actions
    //CCMoveTo * actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-monster.contentSize.width/2, actualY)];
    
    ccBezierConfig bezier;
    bezier.controlPoint_1 = ccp(winSize.width*2/3, actualY+50);
    bezier.controlPoint_2 = ccp(winSize.width/3, actualY+50);
    bezier.endPosition = ccp(-monster.contentSize.width/2,actualY-50);
    
    id actionMove = [CCBezierTo actionWithDuration:actualDuration bezier:bezier];
    
    CCCallBlockN * actionMoveDone = [CCCallBlockN actionWithBlock:^(CCNode *node) {
        [_monsters removeObject:node];
        [node removeFromParentAndCleanup:YES];
        /*CCScene *gameOverScene = [GameOverLayer sceneWithWon:NO];
         [[CCDirector sharedDirector] replaceScene:gameOverScene];*/
    }];
    [monster runAction:[CCSequence actions: actionMove, actionMoveDone, nil]];
    
}

-(void)scrollBackGround:(ccTime)dt
{
    float dtt = dt*10;
    
    //move 30*dt px vertically
    _stars.position = ccp(_stars.position.x+dtt, _stars.position.y );
    _stars2.position = ccp(_stars2.position.x+dtt, _stars2.position.y);
    
    CGSize winSize = [CCDirector sharedDirector].winSize;
    
    //reset offscreen position
    if (_stars.position.x > (winSize.width+_stars.contentSize.width/2))
    {
        _stars.position = ccp(-_stars.contentSize.width/2, winSize.height/2);
    }else if (_stars2.position.x > (winSize.width+_stars2.contentSize.width/2))
    {
        _stars2.position = ccp(-_stars.contentSize.width/2, winSize.height/2);
    }
}

-(void)gameLogic:(ccTime)dt {
    [self addMonster];
}


-(void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    _toLocation = [self convertTouchToNodeSpace:touch];
    [self schedule:@selector(moveCannon:)];
    [self schedule:@selector(createProjectile:) interval:0.2];
    
}

-(void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    UITouch *touch = [touches anyObject];
    _toLocation = [self convertTouchToNodeSpace:touch];
}

-(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    //CGSize winSize = [CCDirector sharedDirector].winSize;
    _toLocation = CGPointZero;
    [self unschedule:@selector(createProjectile:)];
    [self unschedule:@selector(moveCannon:)];
}

-(void)moveCannon:(ccTime)dt {
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    if(CGPointEqualToPoint(_toLocation, CGPointZero)) return;
    
    float toAngle = atanf((_toLocation.y- CENTRE_TERRE_Y)/(_toLocation.x-winSize.width/2));
    
    if(toAngle < M_PI/4 && toAngle > 0) toAngle = M_PI/4;
    if(toAngle > -M_PI/4 && toAngle < 0) toAngle = 3*M_PI/4;
    
    if(toAngle < 0) toAngle += M_PI;
    
    float diff = fabsf(toAngle-_currentAngle);
    if(diff < 0.01) return;
    
    
    float anglePerTick = sqrtf(diff)*dt*5;
    if(toAngle < _currentAngle) anglePerTick = -anglePerTick;
    
    _currentAngle += anglePerTick;
    
    if(_currentAngle < M_PI/4 || _currentAngle > 3*M_PI/4) return;
    
    _player.position = ccpAdd(ccpMult(ccpForAngle(_currentAngle), RAYON_CANNON), CGPointMake(winSize.width/2, CENTRE_TERRE_Y));
    _player.rotation = - CC_RADIANS_TO_DEGREES(_currentAngle - M_PI/2); // Convert from radians to degrees
}

-(void)createProjectile:(ccTime)dt {
    
    // Set up initial location of projectile
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    CCSprite *projectile = [CCSprite spriteWithFile:@"photon.png"];
    
    projectile.tag = 2;
    [_projectiles addObject:projectile];
    
    projectile.position = ccpAdd(ccpMult(ccpForAngle(_currentAngle), RAYON_CANNON+_player.contentSize.height/2), CGPointMake(winSize.width/2, CENTRE_TERRE_Y));
    projectile.rotation = -CC_RADIANS_TO_DEGREES(_currentAngle); // Convert from radians to degrees
    
    int realX;
    int realY;
    
    if(_currentAngle < _angleCoin) {
        realX = winSize.width;
        realY = (tanf(_currentAngle)*(winSize.width/2)+ CENTRE_TERRE_Y);
    }
    else if (_currentAngle < M_PI-_angleCoin) {
        realX =  (winSize.width/2)+((winSize.height- CENTRE_TERRE_Y)/tanf(_currentAngle));
        realY =  winSize.height;
    }
    else {
        realX = -(projectile.contentSize.width/2);
        realY = (tanf(M_PI - _currentAngle)*(winSize.width/2)+ CENTRE_TERRE_Y);
    }
    
    // Ok to add now - we've double checked position
    [self addChild:projectile];
    
    CGPoint realDest = ccp(realX, realY);
    
    // Determine the length of how far you're shooting
    int offRealX = realX - projectile.position.x;
    int offRealY = realY - projectile.position.y;
    float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY));
    float velocity = 320*IPHONE_SCALE; // 480pixels/1sec
    float realMoveDuration = length/velocity;
    
    //[[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"];
    
    // Move projectile to actual endpoint
    [projectile runAction:
     [CCSequence actions:
      [CCMoveTo actionWithDuration:realMoveDuration position:realDest],
      [CCCallBlockN actionWithBlock:^(CCNode *node) {
         [_projectiles removeObject:node];
         [node removeFromParentAndCleanup:YES];
     }],
      nil]];
    
}


-(void)update:(ccTime)dt {
    
    [self scrollBackGround:dt];
    
    for(Explosion* explosion in _explosions){
        
    }
    
    NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];
    for (CCSprite *projectile in _projectiles) {
        
        NSMutableArray *monstersToDelete = [[NSMutableArray alloc] init];
        for (CCSprite *monster in _monsters) {
            
            if (CGRectIntersectsRect(projectile.boundingBox, monster.boundingBox)) {
                [monstersToDelete addObject:monster];
            }
        }
        
        for (CCSprite *monster in monstersToDelete) {
            [_monsters removeObject:monster];
            
            CCParticleSystemQuad* boomParticule = [CCParticleSystemQuad particleWithFile:@"ExplodingRing.plist"];
            boomParticule.position=monster.position;
            boomParticule.scale=IPHONE_SCALE;
            [self addChild:boomParticule z:1 tag:1];
            [boomParticule release];
            [boomParticule stopAllActions];
            
            [self removeChild:monster cleanup:YES];
            
            /*_monstersDestroyed++;
             if (_monstersDestroyed > 20) {
             CCScene *gameOverScene = [GameOverLayer sceneWithWon:YES];
             [[CCDirector sharedDirector] replaceScene:gameOverScene];
             }*/
        }
        
        if (monstersToDelete.count > 0) {
            [projectilesToDelete addObject:projectile];
        }
        [monstersToDelete release];
    }
    
    for (CCSprite *projectile in projectilesToDelete) {
        [_projectiles removeObject:projectile];
        [self removeChild:projectile cleanup:YES];
    }
    [projectilesToDelete release];
}

@end
